home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/tcsh
-
- # Copyright (C) 1989 Free Software Foundation, Inc.
- #
- # genclass program enhanced by Wendell C. Baker
- # (original by Doug Lea (dl@rocky.oswego.edu))
-
- #This file is part of GNU libg++.
-
- #GNU libg++ is free software; you can redistribute it and/or modify
- #it under the terms of the GNU General Public License as published by
- #the Free Software Foundation; either version 1, or (at your option)
- #any later version.
-
- #GNU libg++ is distributed in the hope that it will be useful,
- #but WITHOUT ANY WARRANTY; without even the implied warranty of
- #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- #GNU General Public License for more details.
-
- #You should have received a copy of the GNU General Public License
- #along with GNU libg++; see the file COPYING. If not, write to
- #the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- set echo_style=both
- #
- # genclass -list [proto ...]
- # genclass -catalog [proto ...]
- # genclass type1 {ref|val} proto [out_prefix]
- # genclass -2 type1 {ref|val} type2 {ref, val} proto [out_prefix]
- #
- # Generate classes from prototypes
- #
- set name=genclass ;
- set usage="\n $name -list [proto ...]\n $name -catalog [proto ...]\n $name type1 {ref|val} proto [out_prefix]\n $name -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]"
-
- switch ("$1")
- case -usage:
- #
- # -usage
- #
- echo "usage: $usage";
- exit 0;
- breaksw
- case -version:
- #
- # -version
- #
- # <VERSION> is substituted by the build process.
- # We currently use the libg++ version number (extracted from ../Makefile).
- echo "$name: version 2.5.2" ;
- exit 0;
- breaksw;
- case -requires:
- #
- # -requires
- #
- # The following line should contain any nonstandard programs
- # which must be in the users's path (i.e. not referenced by a
- # fullpath);it allows one to check a script for dependencies
- # without exhaustively testing its usages.
- # ... in this case genclass depends on nothing else.
- echo ;
- exit 0;
- breaksw;
- endsw
-
- # pull it in from the environment
- #[ "$TRACE" = "" ] || set -xv
-
- # Search in standard g++ prototype directory and in the current directory
- # NOTE: this variable is edited by the install process
- set PROTODIR=/usr/local/lib/c++proto
-
- set pwd=$PWD ;
-
- switch ("$1")
- case -list: #*|-catalog*:
- #
- # genclass -catalog [proto ...]
- # genclass -list [proto ...]
- #
- set option="$1" ;
- shift ;
-
- switch ($#)
- case 0:
- #
- # -catalog
- # -list
- #
- set select=all ;
- set select_pattern=p ;
- breaksw
- default:
- #
- # -catalog proto ...
- # -list proto ...
- #
- set select="$@" ;
- select_pattern= ;
- foreach i ($@)
- set select_pattern="\
- $select_pattern\
- /.*$i\$/ p\
- " ;
- end ;
-
- breaksw
- endsw
-
- #
- # select_pattern is now a (possibly-vacuous) newline-
- # separated list of patterns of the form:
- #
- # /.*Proto1$/ p
- # /.*Proto2$/ p
- # /.*Proto3$/ p
- #
- # or select_pattern is simply ``p'' to select everything
-
- # Hmmm... not all systems have a fmt program; should we
- # just go ahead and use ``nroff -Tcrt | cat -s'' here?
- set fmt='nroff -Tcrt | cat -s'
- #fmt=fmt ;
-
- switch ("$option")
- case -catalog:
- #
- # -catalog [proto ...]
- #
- echo "\
- Catalog of ${name} class templates\
- directories searched:\
- $PROTODIR\
- $pwd\
- selecting: $select\
- classes available:" ;
- breaksw
- case -list:
- #
- # -list [proto ...]
- #
- # no need to do anything (the list is coming out next)
- breaksw
- endsw
-
- # The sed script does the following:
- # - If it does not end in a .ccP or .hP then
- # it's not a template and we are not intereseted.
- # - Get rid of pathname components [s;.*/;;]
- # - Just take the template names
- # - change quoting conventions and select off what we want to see
- # -if it did not pass the patterns, kill it
-
- ls $pwd $PROTODIR | sed -ne '\
- /\.ccP$/ !{ \
- /\.hP$/ !{ \
- d \
- } \
- } \
- s;.*/;;\
- s/\.ccP$//\
- s/\.hP$//\
- ' -e "$select_pattern" | sort -u | switch ("$option")
- case -catalog:
- # The library catalog information preceded the list
- # format the list, and tab in in a bit to make it readable.
- # Re-evaluate $fmt because it might contain a shell command
- eval $fmt | sed -e 's/.*/ &/' ;
- breaksw
- case -list:
- # nothing special, just let the sorted list dribble out
- # we must use cat to receive (and reproduce) the incoming list
- cat ;
- breaksw
- exit 0;
- breaksw
- case -2:
- #
- # genclass -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]
- #
- set N=2 ;
-
- switch ($#)
- case [6]: # genclass -2 type1 {ref|val} type2 {ref|val} proto
- breaksw
- case [7]: # genclass -2 type1 {ref|val} type2 {ref|val} proto out_prefix
- breaksw
- default:
- echo "usage: $usage" ;
- exit 1;
- breaksw;
- endsw
- shift ;
- breaksw
- default:
- #
- # genclass type1 {ref|val} proto [out_prefix]
- #
- set N=1 ;
-
- switch ($#)
- case [3]: # genclass type1 {ref|val} proto
- breaksw;
- case [4]: # genclass type1 {ref|val} proto out_prefix
- breaksw;
- default:
- echo "usage: $usage" ;
- exit 1;
- breaksw
- endsw
- breaksw
- endsw
-
- #
- # Args are now (the point being the leading ``-2'' is gone)
- #
- # type1 {ref|val} proto [out_prefix]
- # type1 {ref|val} type2 {ref|val} proto [out_prefix]
- #
-
- #
- # Quote all of the $1 $2 etc references to guard against
- # dynamic syntax errors due to vacuous arguments (i.e. '')
- # as sometimes occurs when genclass is used from a Makefile
- #
-
- set T1="$1";
- set T1NAME="${T1}." ;
- set T1SEDNAME="$T1" ;
-
- switch ("$2")
- case ref:
- set T1ACC="\&" ;
- breaksw
- case val:
- set T1ACC=" " ;
- breaksw
- default:
- echo "${name}: Must specify type1 access as ref or val" ;
- echo "usage: $usage" ;
- exit 1
- breaksw
- endsw
-
- # N is either 1 or 2
-
- switch ($N)
- case 1:
- #
- # type1 {ref|val} proto [out_prefix]
- #
- set class="$3" ;
-
- set T2="" ;
- set T2ACC="" ;
- set T2NAME="";
- breaksw
- case 2:
- #
- # type1 {ref|val} type2 {ref|val} proto [out_prefix]
- #
- set class="$5" ;
-
- set T2="$3";
- set T2NAME="$T2." ;
- set T2SEDNAME="$T2" ;
-
- switch ("$4")
- case ref:
- set T2ACC="\&" ;
- breaksw;
- case val:
- set T2ACC=" " ;
- breaksw;
- default:
- echo "${name}: Must specify type2 access: ref or val" ;
- echo "usage: $usage" ;
- exit 1;
- breaksw;
- endsw
- endsw
-
- set defaultprefix="$T1NAME$T2NAME" ;
-
- switch ($#)
- case [3]: # type1 {ref|val} proto
- set replaceprefix="N" ;
- set prefix="$defaultprefix" ;
- breaksw;
- case [5]: # type1 {ref|val} type2 {ref|val} proto
- set replaceprefix="N" ;
- set prefix="$defaultprefix" ;
- breaksw;
- case [4]: # type1 {ref|val} proto out_prefix
- set prefix="$4" ;
- set replaceprefix="Y" ;
- breaksw;
- case [6]: # type1 {ref|val} type2 {ref|val} proto out_prefix
- set prefix="$6" ;
- set replaceprefix="Y" ;
- breaksw;
- default:
- echo "${name}: too many arguments" ;
- echo "usage: $usage" ;
- exit 1;
- breaksw;
- endsw ;
-
- set src_h=$class.hP
- set src_cc=$class.ccP
- set out_h=$prefix$class.h;
- set out_cc=$prefix$class.cc ;
-
- #
- # Note #1: The .h and .cc parts are done separately
- # in case only a .h exists for the prototype
- #
- # Note #2: Bind the .h and .cc parts to the fullpath
- # directories at the same time to ensure consistency.
- #
-
- if (-f $pwd/$src_h) then
- set fullsrc_h=$pwd/$src_h ;
- set fullsrc_cc=$pwd/$src_cc ;
- else if ( -f $PROTODIR/$src_h ) then
- set fullsrc_h=$PROTODIR/$src_h ;
- set fullsrc_cc=$PROTODIR/$src_cc ;
- else
- echo "${name}: there is no prototype for class $class - file $src_h" ;
- $0 -list ;
- exit 1;
- endif
-
- set CASES="$N$replaceprefix" ;
- # CASES is one of { 2Y 2N 1Y 1N }
-
- #
- # WATCHOUT - we have no way of checking whether or not
- # the proper case type is being used with the prototype.
- #
- # For example, we have no way of ensuring that any of
- # Map variants are specified with the -2 argument set
- # Further, we have no way of ensuring that -2 is not
- # used with the prototypes which require only one.
- #
- # The second problem is not serious because it still
- # results in correctly-generated C++ code; the first
- # problem is serious because it results in C++ code that
- # still has ``<C>'' and ``<C&>'' syntax inside it. Such
- # code of course will not compile.
- #
- # SO THE BEST WE CAN DO - is check for the presence of
- # <C> and <C&> AFTER the thing has been generated.
- #
-
- switch ($CASES)
- case 2Y: # Two output substitutions, change the prefix
- sed < $fullsrc_h > $out_h -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/<C>/$T2/g\
- s/<C&>/$T2$T2ACC/g \
- s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g\
- s/$T1SEDNAME\./$prefix/g\
- s/$T2SEDNAME\./$prefix/g\
- " ;
- breaksw;
- case 2N: # Two output substitutions, use the default prefix
- sed < $fullsrc_h > $out_h -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/<C>/$T2/g\
- s/<C&>/$T2$T2ACC/g\
- " ;
- breaksw;
- case 1Y: # One output substitution, change the prefix
- sed < $fullsrc_h > $out_h -e "
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/$T1SEDNAME\./$prefix/g\
- " ;
- breaksw;
- case 1N: # One output substitution, use the default prefix
- sed < $fullsrc_h > $out_h -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- " ;
- breaksw;
- endsw
-
- fgrep '<C&?>' $out_h > /dev/null
- if ( $? == 0) then
- echo "${name}: the $class class requires the -2 syntax for the 2nd type" ;
- echo "usage: $usage" ;
- # the user does not get to see the mistakes (he might try to compile it)
- rm $out_h ;
- exit 1;
- endif
-
- if ( ! -f $fullsrc_cc ) then
- echo "${name}: warning, class has a .h but no .cc file" ;
- exit 0;
- endif
-
- switch ($CASES)
- case 2Y: # Two output substitutions, change the prefix
- sed < $fullsrc_cc > $out_cc -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/<C>/$T2/g\
- s/<C&>/$T2$T2ACC/g\
- s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g\
- s/$T1SEDNAME\./$prefix/g\
- s/$T2SEDNAME\./$prefix/g\
- "
- breaksw;
- case 2N: # Two output substitutions, use the default prefix
- sed < $fullsrc_cc > $out_cc -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/<C>/$T2/g\
- s/<C&>/$T2$T2ACC/g\
- "
- breaksw;
- case 1Y: # One output substitution, change the prefix
- sed < $fullsrc_cc > $out_cc -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- s/$T1SEDNAME\./$prefix/g\
- "
- breaksw;
- case 1N: # One output substitution, use the default prefix
- sed < $fullsrc_cc > $out_cc -e "\
- s/<T>/$T1/g\
- s/<T&>/$T1$T1ACC/g\
- "
- breaksw;
- endsw
-
- fgrep '<C&?>' $out_h $out_cc > /dev/null
- if ($? == 0) then
- echo "${name}: the $class class requires the -2 syntax for the 2nd type" ;
- echo "usage: $usage" ;
- # the user does not get to see the mistakes (he might try to compile it)
- rm $out_h $out_cc ;
- exit 1;
- endif ;
-
- exit 0;
-